#include "stdc/stdc++.h"
template <typename T> class Iterator
{
   public:
    virtual void first() = 0;
    virtual void next() = 0;
    virtual bool isDone() const = 0;
    virtual T &current() = 0;
    virtual ~Iterator() {}
};

template <typename T> class ICollection
{

   public:
    virtual Iterator<T> *GetIterator() = 0;
    virtual int GetSize() = 0;
    virtual T &GetItem(int index) = 0;
    virtual ~ICollection() {}
};

template <typename T> class CollectionIterator : public Iterator<T>
{
    ICollection<T> *mc;
    int idx;

   public:
    CollectionIterator(ICollection<T> *c) : mc(c), idx(0) {}

    void first() override
    {
        idx = 0;
    }
    void next() override
    {
        if (idx < mc->GetSize())
            idx++;
    }
    bool isDone() const override
    {
        return idx == mc->GetSize();
    }
    T &current() override
    {
        return mc->GetItem(idx);
    }
};
template <typename T> class MyCollection : public ICollection<T>
{
   private:
    T *Object;
    int size;

   public:
    MyCollection(int size)
    {
        Object = (T *)malloc(size * sizeof(T));

        for (int i = 0; i < size; i++)
            Object[i] = 65 + i;

        this->size = size;
    }

    virtual Iterator<T> *GetIterator()
    {
        return new CollectionIterator<T>(this);
    }

    virtual int GetSize()
    {
        return this->size;
    }

    virtual T &GetItem(int index)
    {
        return this->Object[index];
    }

    ~MyCollection()
    {
        delete Object;
    }
};
int main()
{
    ICollection<int> *p_mc = new MyCollection<int>(10);

    Iterator<int> *iter = p_mc->GetIterator();

    for (iter->first(); !iter->isDone(); iter->next())
    {
        std::cout << iter->current() << std::endl;
    }
}
